package com.huluobo.a2203kotlinjetpackdemo.coroutine

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.lifecycle.lifecycleScope
import com.huluobo.a2203kotlinjetpackdemo.databinding.ActivityFlowBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

/**
 * flow:
 * Kotlin中的数据流,可以发送多条数据,可以按照顺序发送多个值
 * 1.emit是发送的意思,必须要有个collect接收
 * 2.flow是一个挂起方法,必须运行在协程中
 * 3.flow是数据流,但是是一个冷流,冷流:是在数据被订阅之后,发布者才会执行发射数据流的代码(类似懒加载)
 * 4.collect是订阅,收集的意思,一个flow中必须要有订阅后才能发送数据(只针对冷流)
 * 5.filter是过滤器,可以将发送的内容进行判断和过滤在被订阅者接收
 * 6.map是转化器,可以将发送的数据流转换为任意类型的对象再发送
 */
class FlowActivity : AppCompatActivity() {
    private lateinit var activityFlowBinding: ActivityFlowBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activityFlowBinding = ActivityFlowBinding.inflate(layoutInflater)
        setContentView(activityFlowBinding.root)
        lifecycleScope.launch(Dispatchers.Main) {
            loadData().collect {
                Log.i("TagA", it.toString())
            }
            loadData2().collect {
                Log.i("TagA", "$it")
            }
        }

    }

    private fun loadData() = flow {
        Log.i("TagA", "进入loadData方法")
        for (i in 1..10) {
            kotlinx.coroutines.delay(1000)
            emit(i)//发送数据
        }
    }.filter {
        it % 2 == 0 //添加判断,用于过滤发送的结果
    }

    private fun loadData2() = flow {
        Log.i("TagA", "进入loadData2方法")

        for (i in 1..10) {
            kotlinx.coroutines.delay(1000)
            emit(i)
        }
    }.filter {
        it % 2 == 0
    }.map {
        (it * 5).toString() //用于转化,可以输出另外的对象
    }.flowOn(Dispatchers.IO)
        .catch { catch ->
            //当flow流禅城错误时
            Log.i("TagA", catch.message.toString())
        }
}